package com.study.yangfei.mystudy.activity;

import android.os.Bundle;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;

import com.study.yangfei.mystudy.R;
import com.study.yangfei.mystudy.utils.TimingLoggerYF;

import java.math.BigInteger;

public class AlogFibonacciActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alog_fibonacci);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().build());

        int fIndex = 1024*100;

        TimingLoggerYF timings = new TimingLoggerYF("TimingLogger", "methodA");

        long fb = getFibonacci(fIndex);
        timings.addSplit("getFibonacci");

        long fbEx = getFibonacciEx(fIndex);
        timings.addSplit("getFibonacciEx");

        BigInteger fbExBig  = getFibonacciExBig(fIndex);
        timings.addSplit("fbExBig");

        timings.dumpToLog();
        Log.e("AlogFibonacciActivity","fb = "+fb);
        Log.e("AlogFibonacciActivity","fbEx = "+fbEx);
        Log.e("AlogFibonacciActivity","fbExBig = "+fbExBig.toString());

//        StrictMode.noteSlowCall("getFibonacciExBig");
    }

    public long getFibonacci(int n){
        long a = 0;
        long b = 1;
        if(n < 2 )
            return 1;
        while(n-->0){
            long s = a + b;
            a = b;
            b = s;
        }
        return a;
    }

    public long getFibonacciEx(int n){
        if(n>1){
            long a,b=1;
            n--;
            a = n&1;
            n/=2;
            while(n-->0){
                a+=b;
                b+=a;
            }
            return b;
        }
        return n;
    }

    public BigInteger getFibonacciExBig(int n){
        StrictMode.noteSlowCall("getFibonacciExBig");
        if(n>1){
            BigInteger a;
            BigInteger b=BigInteger.ONE;
            n--;
            a = BigInteger.valueOf(n&1);
            n/=2;
            while(n-->0){
                a = a.add(b);
                b = b.add(a);
            }
            return b;
        }
        if(n == 0)
            return BigInteger.ZERO;
        if(n == 1)
            return BigInteger.ONE;

        return null;
    }

}
